﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace paddle_ocrlabel
{
    public class Shape
    {
        public Shape()
        {
            marks = new List<Mark>();

            topLeftMark = new Mark(this, Cursors.SizeNWSE) { Pos = 0 };
            topRightMark = new Mark(this, Cursors.SizeNESW) { Pos = 1 };
            bottomRightMark = new Mark(this, Cursors.SizeNWSE) { Pos = 2 };
            bottomLeftMark = new Mark(this, Cursors.SizeNESW) { Pos = 3 };

            this.marks.Add(topLeftMark);
            this.marks.Add(topRightMark);
            this.marks.Add(bottomRightMark);
            this.marks.Add(bottomLeftMark);
        }

        public List<PointF> points { get; set; }

        Mark topLeftMark;
        Mark topRightMark;
        Mark bottomRightMark;
        Mark bottomLeftMark;

        private List<Mark> marks;
        public List<Mark> Marks
        {
            get { return marks; }
        }

        public bool In(int x, int y)
        {
            int counter = 0;
            int i;

            double xinters;
            PointF p1, p2;
            int pointCount = this.points.Count;
            p1 = this.points[0];

            for (i = 1; i <= pointCount; i++)
            {
                p2 = this.points[i % pointCount];

                if (y > Math.Min(p1.Y, p2.Y)//校验点的Y大于线段端点的最小Y
                    && y <= Math.Max(p1.Y, p2.Y))//校验点的Y小于线段端点的最大Y 
                {
                    if (x <= Math.Max(p1.X, p2.X))//校验点的X小于等线段端点的最大X(使用校验点的左射线判断). 
                    {
                        if (p1.Y != p2.Y)//线段不平行于X轴     
                        {
                            xinters = (y - p1.Y) * (p2.X - p1.X) / (p2.Y - p1.Y) + p1.X;
                            if (p1.X == p2.X || x <= xinters)
                            {
                                counter++;
                            }
                        }
                    }
                }
                p1 = p2;
            }
            if (counter % 2 == 0) { return false; } else { return true; }
        }

        public Canvas Canvas
        {
            get;
            set;
        }

        private bool selected;
        public bool Selected
        {
            get { return selected; }
            set
            {
                selected = value;
                if (selected && this.Canvas != null)
                {
                    foreach (Shape s in Canvas.Shapes)
                        if (s != this)
                            s.Selected = false;
                }
            }
        }

        public bool isNew { get; set; }
        public String text { get; set; }

        public void MoveTo(Point point)
        {
            int gap_x = point.X - (int)points[0].X;
            int gap_y = point.Y - (int)points[0].Y;

            PointF p0 = new PointF(points[0].X + gap_x, points[0].Y + gap_y);
            PointF p1 = new PointF(points[1].X + gap_x, points[1].Y + gap_y);
            PointF p2= new PointF(points[2].X + gap_x, points[2].Y + gap_y);
            PointF p3 = new PointF(points[3].X + gap_x, points[3].Y + gap_y);

            this.points.Clear();
            this.points.Add(p0);
            this.points.Add(p1);
            this.points.Add(p2);
            this.points.Add(p3);
        }

        public void MoveOnePointTo(int pos, int x, int y)
        {
            points[pos] = new PointF(x, y);        
        }

        public void MoveThreePointsTo(int x, int y, PointF duijiaoPoint)
        {            
            int left = Math.Min((int)duijiaoPoint.X, x);
            int top = Math.Min((int)duijiaoPoint.Y, y);
            int width = Math.Abs((int)duijiaoPoint.X - x);
            int height = Math.Abs((int)duijiaoPoint.Y - y);

            points[0] = new PointF(left, top);
            points[1] = new PointF(left + width, top);
            points[2] = new PointF(left + width, top + height);
            points[3] = new PointF(left, top + height);
        }

        public override string ToString()
        {
            String result = "";
            foreach (var point in points)
            {
                result += String.Format("({0},{1}),", point.X, point.Y);
            }

            return "[" + result.Substring(0, result.Length - 1) + "]";
        }

        public bool isRec()
        {
            if(this.points[0].Y == this.points[1].Y && this.points[2].Y == this.points[3].Y
                && this.points[0].X == this.points[3].X && this.points[1].X == this.points[2].X)
            {
                return true;
            }
            else if(this.points[0].X == this.points[1].X && this.points[2].X == this.points[3].X
              && this.points[0].Y == this.points[3].Y && this.points[1].Y == this.points[2].Y)
            {
                return true;
            }

            return false;
        }
    }
}
